package com.youhome.service.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSSClient;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.youhome.common.config.OSSConfig;
import com.youhome.common.config.USAConfig;
import com.youhome.common.exception.CustomException;
import com.youhome.common.response.ResultCode;
import com.youhome.service.listhub.*;
import com.youhome.service.mapper.HouseFloorPlanMapper;
import com.youhome.service.mapper.ListHubMapper;
import com.youhome.service.mapper.ListHubPhotoMapper;
import com.youhome.service.model.*;
import com.youhome.service.parameter.ParamOwnHouse;
import com.youhome.service.response.*;
import com.youhome.service.service.*;
import com.youhome.service.utils.AddressUtils;
import com.youhome.utils.*;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * Created by chen365 on 2018/05/09.
 */
@Service
public class ListHubServiceImpl implements ListHubService {
    @Autowired
    private BUserService bUserService;
    @Autowired
    private ListHubMapper listHubMapper;
    @Autowired
    private OSSConfig ossConfig;
    @Autowired
    private ListHubPhotoMapper listHubPhotoMapper;
    @Autowired
    private HouseFloorPlanMapper houseFloorPlanMapper;
    @Autowired
    private DownloadService downloadService;
    @Autowired
    private SolrService solrService;
    @Autowired
    private OSSService ossService;
    @Autowired
    private HomeJunctionService homeJunctionService;
    @Autowired
    private BCompanyService bCompanyService;
    @Autowired
    private TranslateService translateService;
    @Autowired
    private ZillowService zillowService;
    @Autowired
    private TruliaDataService truliaDataService;
    @Autowired
    private CityDataService cityDataService;
    @Autowired
    private ZipService zipService;
    @Autowired
    private USAConfig usaConfig;
    @Autowired
    private UnemploymentService unemploymentService;

    @Override
    public int updateByPrimaryKeySelective(ListHub record) {
        return listHubMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public ListHub selectByPrimaryKey(String houseId) {
        return listHubMapper.selectByPrimaryKey(houseId);
    }

    @Override
    public PageInfo<ListHubList> selectByBean(Integer pageIndex, Integer pageSize, ListHubParam param) {
        if (StringUtils.isEmpty(pageIndex) || pageIndex < 1) {
            pageIndex = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 10) {
            pageSize = 10;
        }
        PageHelper.startPage(pageIndex, pageSize);
        param.setEnabled(true);
        List<ListHubList> list = listHubMapper.selectByBean(param);
        return new PageInfo<>(list);
    }

    @Override
    public List<HouseMap> selectMapByBean(ListHubParam param) {
        return listHubMapper.selectMapByBean(param);
    }

    @Override
    public List<ListHubList> selectRecommendHouseByCompanyId(Long companyId) {
        return listHubMapper.selectRecommendHouseByCompanyId(companyId);
    }

    @Override
    public List<ListHubList> selectShareGroupHouseByShareId(String shareId) throws CustomException {
        if (StringUtils.isEmpty(shareId)) {
            throw new CustomException(ResultCode.EMPTY_PARAM);
        }
        return listHubMapper.selectShareGroupHouseByShareId(shareId);
    }

    @Override
    public List<HouseCircum> selectHouseCircumByBean(Integer pageIndex, Integer pageSize, ListHubParam param) {
        if (StringUtils.isEmpty(pageIndex) || pageIndex < 1) {
            pageIndex = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 6) {
            pageSize = 6;
        }
        PageHelper.startPage(pageIndex, pageSize);
        param.setEnabled(true);
        List<HouseCircum> list = listHubMapper.selectHouseCircumByBean(param);
        return list;
    }

    @Override
    public List<AssociateAddress> selectAssociateByAddress(String address) {
        return listHubMapper.selectAssociateByAddress(address);
    }

    @Override
    public String selectZipByPrimaryKey(String houseId) {
        return listHubMapper.selectZipByPrimaryKey(houseId);
    }

    @Override
    public int save(String houseId, String listingKey, Long companyId, String unitNumber, String fullStreetAddress, String city, String state, String county, String zip,
                    Double listPrice, String listingCategory, String listingStatus, Date listingDate, String listingTitle, String listingDescription,
                    Integer bedroomCount, Integer bathroomCount, Integer fullBathroomCount, Integer threeQuarterBathroomCount, Integer halfBathroomCount,
                    Integer oneQuarterBathroomCount, String propertyType, String propertySubtype, String mlsId, String mlsName, String mlsNumber,
                    Double livingArea, Double lotSize, Integer yearBuilt, String builderName, Double latitude, Double longitude, String parcelId,
                    Boolean isStar, String photos,
                    Boolean isNewHouse,
                    String communityName,
                    String housesName,
                    Double forecastRent,
                    Double forecastPropertyFee,
                    Double forecastHousePropertyTax, String floorPlans) {

        String address = AddressUtils.getAddress(unitNumber, fullStreetAddress, city, state, zip);

        ListHub record = new ListHub();

        Boolean isUpdate = true;

        if (StringUtils.isEmpty(houseId)) {
            listingKey = "youhome-" + StringUtils.getDateRandomName();
            houseId = DigestUtils.md5Hex(listingKey);
            isUpdate = false;
        }

        record.setHouseId(houseId);

        record.setAddress(address);
        record.setCity(city);
        record.setProvince(state);
        record.setZip(zip);
        record.setCounty(county);

        record.setListingKey(listingKey);
        record.setListingDate(listingDate);
        record.setListingCategory(listingCategory);
        record.setListPrice(listPrice);
        record.setListingStatus(listingStatus);
        record.setListingTitle(listingTitle);
        record.setListingDescription(listingDescription);

        record.setBedroomCount(bedroomCount);
        record.setBathroomCount(bathroomCount);
        record.setFullBathroomCount(fullBathroomCount);
        record.setThreeQuarterBathroomCount(threeQuarterBathroomCount);
        record.setHalfBathroomCount(halfBathroomCount);
        record.setOneQuarterBathroomCount(oneQuarterBathroomCount);

        record.setPropertyType(propertyType);
        record.setPropertySubtype(propertySubtype);
        record.setMlsId(mlsId);
        record.setMlsName(mlsName);

        record.setLivingArea(livingArea);
        record.setLotSize(lotSize);
        record.setLongitude(longitude);
        record.setLatitude(latitude);
        record.setYearBuilt(yearBuilt);
        record.setBuilderName(builderName);
        record.setParcelId(parcelId);
        record.setIsStar(isStar);

        record.setCreateTime(new Date());
        record.setModificationTimestamp(new Date());
        record.setEnabled(true);
        record.setDataSource("YouHome");
        record.setCompanyId(companyId);

        record.setIsNewHouse(isNewHouse);
        record.setCommunityName(communityName);
        record.setHousesName(housesName);
        record.setForecastRent(forecastRent);
        record.setForecastPropertyFee(forecastPropertyFee);
        record.setForecastHousePropertyTax(forecastHousePropertyTax);

        if (!StringUtils.isEmpty(photos)) {
            String[] array = photos.split(",");
            record.setHeroImage(array[0]);
        }


        System.err.println(record.toString());

        int row;
        if (isUpdate) {
            row = listHubMapper.updateByPrimaryKeySelective(record);
        } else {
            row = listHubMapper.insertSelective(record);
        }
        if (row == 1) {

            solrService.saveHouseIndex(record.getHouseId());

            //上传图片
            if (!StringUtils.isEmpty(photos)) {
                String[] array = photos.split(",");
                List<ListHubPhoto> list = new ArrayList<>();
                int k = 0;
                for (String str : array) {
                    ListHubPhoto photo = new ListHubPhoto();
                    photo.setHouseId(houseId);
                    if (k == 0) {
                        photo.setIsMain(true);
//                        ListHub listHub = new ListHub();
//                        listHub.setHouseId(houseId);
//                        listHub.setHeroImage(str);
                        //修改列表主图
                        //listHubMapper.updateByPrimaryKeySelective(listHub);
                    } else {
                        photo.setIsMain(false);
                    }
                    photo.setIsDownload(true);
                    photo.setDownloadStatus(1);
                    photo.setOssUrl(str);
                    photo.setOssModificationTimestamp(new Date());
                    photo.setSource("YouHome");
                    list.add(photo);
                    k++;
                }
                if (list.size() > 0) {
                    listHubPhotoMapper.insertBatch(list);
                }
            }
            //上传平面设计图
            if (!StringUtils.isEmpty(floorPlans)) {
                String[] array = floorPlans.split(",");
                List<HouseFloorPlan> list = new ArrayList<>();

                for (String str : array) {
                    HouseFloorPlan floorPlan = new HouseFloorPlan();
                    floorPlan.setHouseId(houseId);
                    floorPlan.setPhoto(str);
                    list.add(floorPlan);
                }
                if (list.size() > 0) {
                    houseFloorPlanMapper.insertBatch(list);
                }
            }

            //创建json 并上传oss
            createJson(listingKey, unitNumber, fullStreetAddress, city, state, county, zip,
                    listPrice, listingCategory, listingStatus, listingDate, listingTitle, listingDescription,
                    bedroomCount, bathroomCount, fullBathroomCount, threeQuarterBathroomCount, halfBathroomCount,
                    oneQuarterBathroomCount, propertyType, propertySubtype, mlsId, mlsName, mlsNumber,
                    livingArea, lotSize, yearBuilt, builderName, latitude, longitude, parcelId);
        }
        return row;
    }

    @Override
    public int delete(String houseId, Long companyId) {
        ListHub entity = listHubMapper.selectByPrimaryKey(houseId);

        ListHub record = new ListHub();
        record.setHouseId(houseId);
        record.setCompanyId(companyId);
        record.setDataSource("YouHome");
        int row = listHubMapper.deleteByBean(record);
        if (row > 0) {
            if (!StringUtils.isEmpty(entity.getListingKey())) {
                String key = "json/" + entity.getListingKey() + ".json";
                //删除房源json文件
                ossService.delete(key);
            }
            // 删除solr 索引
            solrService.deleteHouseIndex(houseId);

            //取出所有图片
            ListHubPhoto photo = new ListHubPhoto();
            photo.setHouseId(houseId);
            List<ListHubPhoto> listHubPhotos = listHubPhotoMapper.selectByBean(photo);
            //遍历删除图片
            for (ListHubPhoto listHubPhoto : listHubPhotos) {
                listHubPhotoMapper.deleteByBean(listHubPhoto);
                //删除oss里的图片
                ossService.delete(listHubPhoto.getOssUrl());
            }
        }
        return row;
    }

    @Override
    public int updateStar(ListHub record) {
        record.setDataSource("YouHome");
        if (listHubMapper.updateStarByPrimaryKey(record) > 0) {
            solrService.saveHouseIndex(record.getHouseId());
        } else {
            return 0;
        }

        return 1;
    }

    @Override
    public ListHubBase selectBaseByPrimaryKey(String houseId) throws CustomException {
        ListHubBase listHubBase = listHubMapper.selectBaseByPrimaryKey(houseId);
        if (listHubBase == null) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }
        return listHubBase;
    }

    @Override
    public int selectCountByZips(ListHubParam param) {
        return listHubMapper.selectCountByZips(param);
    }

    @Override
    public PageInfo<ListHubList> selectFavouriteHouseByUserId(Integer pageNumber, Integer pageSize, Long userId) {
        if (StringUtils.isEmpty(pageNumber) || pageNumber < 1) {
            pageNumber = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 10) {
            pageSize = 10;
        }
        PageHelper.startPage(pageNumber, pageSize);
        List<ListHubList> listHubLists = listHubMapper.selectFavouriteHouseByUserId(userId);
        return new PageInfo<>(listHubLists);
    }

    @Override
    public List<ListHub> selectTest() {
        return listHubMapper.selectTest();
    }

    @Override
    public PageInfo<ListHubList> selectRandByBean(Integer pageNumber, Integer pageSize, ListHubParam params) {
        if (StringUtils.isEmpty(pageNumber) || pageNumber < 1) {
            pageNumber = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 10) {
            pageSize = 10;
        }
        PageHelper.startPage(pageNumber, pageSize);
        List<ListHubList> list = listHubMapper.selectRandByBean(params);
        return new PageInfo<>(list);
    }

    @Override
    public HoaFeeSchoolGradeResult selectHoaFeeSchoolGrade(String houseId) throws CustomException {
        HoaFeeSchoolGradeResult hoaFeeSchoolGradeResult = new HoaFeeSchoolGradeResult();
        ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);
        if (listHub != null) {
            String listingKey = listHub.getListingKey();
            if (!StringUtils.isEmpty(listingKey)) {
                String key = "json/" + listingKey + ".json";
                try {
                    String json = downloadService.downloadJsonFromOSS(key);
                    if (!StringUtils.isEmpty(json)) {
                        JSONObject jsonObject = JSONObject.fromObject(json);

                        ObjectMapper mapper = new ObjectMapper();

                        //物业费
                        //Home Owner Assessments Fee
                        //额外费用
                        if (!StringUtils.isEmpty(jsonObject.get("expenses")) && !jsonObject.get("expenses").equals("null")) {
                            JSONObject expenses = (JSONObject) jsonObject.get("expenses");
                            if (expenses != null && !expenses.equals("null")) {
                                ListingItemType.Expenses expenses_list = mapper.readValue(expenses.toString(), ListingItemType.Expenses.class);
                                for (ExpensesType item : expenses_list.getExpense()) {
                                    String value = item.getExpenseCategory().getValue();
                                    if (!StringUtils.isEmpty(value) && value.equals("Home Owner Assessments Fee")) {
                                        //物业费
                                        String hoa_fee = item.getExpenseValue().getValue() + "/" + item.getExpenseValue().getCurrencyPeriod();
                                        hoaFeeSchoolGradeResult.setHoa_fee(hoa_fee);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (JsonParseException e) {
                    e.printStackTrace();
                } catch (JsonMappingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            String zip = listHub.getZip();
            if (!StringUtils.isEmpty(zip)) {
                HJSchool record_elementary = new HJSchool();
                record_elementary.setZip(zip);
                Integer elementary_review_rating = homeJunctionService.selectReviewRatingByZipAndGrade(record_elementary);
                hoaFeeSchoolGradeResult.setElementary_review_rating(elementary_review_rating);

                HJSchool record_middle = new HJSchool();
                record_middle.setZip(zip);
                Integer middle_review_rating = homeJunctionService.selectReviewRatingByZipAndGrade(record_middle);
                hoaFeeSchoolGradeResult.setMiddle_review_rating(middle_review_rating);

                HJSchool record_high = new HJSchool();
                record_high.setZip(zip);
                Integer high_review_rating = homeJunctionService.selectReviewRatingByZipAndGrade(record_high);
                hoaFeeSchoolGradeResult.setHigh_review_rating(high_review_rating);
            }
        }

        return hoaFeeSchoolGradeResult;
    }

    @Override
    public PageInfo<ListHubList> selectFavouriteHouseByUserId(Principal principal, Integer pageNumber, Integer pageSize) throws CustomException {

        Long userId = principal.getUser().getUserId();
        if (StringUtils.isEmpty(pageNumber) || pageNumber < 1) {
            pageNumber = 1;
        }
        if (StringUtils.isEmpty(pageSize) || pageSize < 10) {
            pageSize = 10;
        }
        PageHelper.startPage(pageNumber, pageSize);
        return new PageInfo<>(listHubMapper.selectFavouriteHouseByUserId(userId));

    }

    @Override
    public void setStar(String houseId) throws CustomException {
        ListHub listHub = new ListHub();
        if (StringUtils.isEmpty(houseId)) {
            throw new CustomException(ResultCode.ERROR_PARAMETER);
        }
        listHub.setHouseId(houseId);
        Long companyId = bUserService.getCompanyId();
        if (StringUtils.isEmpty(companyId)) {
            throw new CustomException(ResultCode.EXPIRED_LOGIN);
        }
        listHub.setCompanyId(companyId);

        listHub.setDataSource("YouHome");
        if (listHubMapper.updateStarByPrimaryKey(listHub) > 0) {
            solrService.saveHouseIndex(houseId);
        } else {
            throw new CustomException(ResultCode.FAIL);
        }
    }

    @Override
    public void delete(String houseId) throws CustomException {
        if (StringUtils.isEmpty(houseId)) {
            throw new CustomException(ResultCode.ERROR_PARAMETER);
        }
        Long companyId = bUserService.getCompanyId();
        if (delete(houseId, companyId) == 0) {
            throw new CustomException(ResultCode.FAIL);
        }
    }

    @Override
    public void save(ParamOwnHouse record) throws CustomException {
        if (!StringUtils.isEmpty(record.getLongitude()) && !StringUtils.isEmpty(record.getLatitude())) {
            if (!GeoUtils.isCoordinate(record.getLongitude(), record.getLatitude())) {
                throw new CustomException(ResultCode.ERROR_LONGITUDE_LATITUDE);
            }
        }

        Long companyId = bUserService.getCompanyId();
        if (companyId == null) {
            throw new CustomException(ResultCode.EXPIRED_LOGIN);
        }

        int success = save(
                record.getHouseId(), record.getListingKey(), companyId, record.getUnitNumber(), record.getFullStreetAddress(),
                record.getCity(), record.getState(), record.getCounty(), record.getZip(), record.getListPrice(),
                record.getListingCategory(), record.getListingStatus(), DateUtils.getDateByStr(record.getListingDate()),
                record.getListingTitle(), record.getListingDescription(), record.getBedroomCount(), record.getBathroomCount(),
                record.getFullBathroomCount(), record.getThreeQuarterBathroomCount(), record.getHalfBathroomCount(),
                record.getOneQuarterBathroomCount(), record.getPropertyType(), record.getPropertyType(), record.getMlsId(),
                record.getMlsName(), record.getMlsNumber(), record.getLivingArea(), record.getLotSize(), record.getYearBuilt(),
                record.getBuilderName(), record.getLatitude(), record.getLongitude(), record.getParcelId(), record.getIsStar(),
                record.getPhotos(), record.getIsNewHouse(), record.getCommunityName(), record.getHousesName(),
                record.getForecastRent(), record.getForecastPropertyFee(), record.getForecastHousePropertyTax(),
                record.getFloorPlans()
        );

        if (success == 0) {
            throw new CustomException(ResultCode.SUCCESS);
        }
    }


    /**
     * 查询公司下所有推荐房源
     *
     * @return 房源列表
     * @throws CustomException
     */
    @Override
    public List<ListHubList> selectRecommendHouse() throws CustomException {
        BUser currentUser = bUserService.getCurrentUser();
        if (currentUser == null) {
            throw new CustomException(ResultCode.EXPIRED_LOGIN);
        }
        BCompany company = bCompanyService.selectByUserId(currentUser.getUserId());
        if (company == null) {
            throw new CustomException(ResultCode.DATA_DOES_NOT_EXIST_OR_HAS_BEEN_DELETED);
        }
        return listHubMapper.selectRecommendHouseByCompanyId(company.getCompanyId());
    }

    @Override
    public TranslationResult selectListingDescription(String houseId) throws CustomException {
        String listingKey = listHubMapper.selectListingKeyByPrimaryKey(houseId);
        if (StringUtils.isEmpty(listingKey)) {
            throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
        }
        String key = "json/" + listingKey + ".json";
        String json = downloadService.downloadJsonFromOSS(key);
        if (!StringUtils.isEmpty(json)) {
            JSONObject dataJson = JSONObject.fromObject(json);
            if (dataJson.get("listingDescription") != null && !dataJson.get("listingDescription").equals("null")) {
                String listingDescription = (String) dataJson.get("listingDescription");
                return translateService.trans(houseId, listingDescription);
            }
        }
        return null;
    }

    @Override
    public PriceForecastResult selectHomeValueForecast(String houseId) throws CustomException {

        ListHub house = listHubMapper.selectByPrimaryKey(houseId);

        if (house == null) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }
        Double price = house.getListPrice(); //房产价格

        String zip = house.getZip();  //邮编
        String state = house.getProvince(); //州

//            TimeSeriesDataHomeValueForecast homeValueForecast = timeSeriesDataHomeValueForecastService.selectByZipcode(zip);
//            if (homeValueForecast == null)
//                throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
//            Double rise = homeValueForecast.getValue(); //增浮率

        //http://youhome.oss-cn-zhangjiakou.aliyuncs.com/zillow/AllRegionsForePublic/ak_zip_99709.json
        //州与邮编不存在
        if (StringUtils.isEmpty(state) || StringUtils.isEmpty(zip)) {
            throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
        }
        String key = "zillow/AllRegionsForePublic/" + state.toLowerCase() + "_zip_" + zip + ".json";
        String json = downloadService.downloadJsonFromOSS(key);
        //没有数据
        if (StringUtils.isEmpty(json)) {
            throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
        }
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(json);
        //ForecastYoYPctChange  不存在
        if (jsonObject.get("ForecastYoYPctChange") == null) {
            throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
        }
        Double rise = Double.valueOf(jsonObject.getString("ForecastYoYPctChange"));

        Double forecastPrice = price * (1 + rise / 100);

        PriceForecastResult priceForecast = new PriceForecastResult();
        priceForecast.current_price = price;
        priceForecast.forecast_price = forecastPrice;
        priceForecast.rise = rise;
        return priceForecast;

    }

    @Override
    public List<HouseCircum> selectSimilarHousesNearby(String houseId) throws CustomException {
        ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);
        if (listHub == null) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }
        ListHubParam record = new ListHubParam();
        if (listHub.getListPrice() != null && listHub.getListPrice() > 0) {
            record.setMinListPrice(listHub.getListPrice() * 0.8);
            record.setMaxListPrice(listHub.getListPrice() * 1.2);
        }
        if (!StringUtils.isEmpty(listHub.getZip())) {
            record.setZip(listHub.getZip());
        }
        record.setYearBuilt(1980);
        record.setListingStatus("Active");
        record.setEnabled(true);
        record.setIsCheck(true);

        PageHelper.startPage(1, 6);
        List<HouseCircum> houseCircums = listHubMapper.selectHouseCircumByBean(record);

        Double lat1 = listHub.getLatitude();
        Double lng1 = listHub.getLongitude();

        if (!StringUtils.isEmpty(lat1) && !StringUtils.isEmpty(lng1)) {

            for (HouseCircum item : houseCircums) {
                Double lat2 = item.getLatitude();
                Double lng2 = item.getLongitude();
                if (!StringUtils.isEmpty(lat2) && !StringUtils.isEmpty(lng2)) {
                    Double distance = GeoUtils.getDistance(lat1, lng1, lat2, lng2);
                    item.setDistance(DoubleUtils.format(distance));
                }
            }
        }

        HouseCircum houseCircum = new HouseCircum();
        houseCircum.setHouseId(listHub.getHouseId());
        houseCircum.setListPrice(listHub.getListPrice());
        houseCircum.setAddress(listHub.getAddress());
        houseCircum.setLivingArea(listHub.getLivingArea());
        houseCircum.setHeroImage(listHub.getHeroImage());
        houseCircum.setYearBuilt(listHub.getYearBuilt());
        houseCircum.setLatitude(listHub.getLatitude());
        houseCircum.setLongitude(listHub.getLongitude());
        houseCircum.setIsMain(true);
        houseCircum.setDistance((double) 0);
        houseCircum.setBedroomCount(listHub.getBedroomCount());
        houseCircum.setBathroomCount(listHub.getBathroomCount());
        houseCircum.setListingStatus(listHub.getListingStatus());
        houseCircum.setPropertySubtype(listHub.getPropertySubtype());
        houseCircum.setCity(listHub.getCity());
        houseCircums.add(houseCircum);

        return houseCircums;
    }

    @Override
    public Characteristics selectCharacteristics(String houseId) throws CustomException {

        String listingKey = listHubMapper.selectListingKeyByPrimaryKey(houseId);
        if (StringUtils.isEmpty(listingKey)) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }

        String key = "json/" + listingKey + ".json";
        String json = downloadService.downloadJsonFromOSS(key);
        if (StringUtils.isEmpty(json)) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }
        try {
            JSONObject jsonObject = JSONObject.fromObject(json);
            ObjectMapper mapper = new ObjectMapper();
            //房源特征
            if (jsonObject.get("detailedCharacteristics") != null && !jsonObject.get("detailedCharacteristics").equals("null")) {
                JSONObject characteristics = (JSONObject) jsonObject.get("detailedCharacteristics");
                if (characteristics != null && !characteristics.equals("null")) {
                    DetailedCharacteristicsType detailedCharacteristicsType = mapper.readValue(characteristics.toString(), DetailedCharacteristicsType.class);

                    Characteristics detailedCharacteristics = new Characteristics();
                    //电器
                    if (detailedCharacteristicsType.getAppliances() != null && !detailedCharacteristicsType.getAppliances().equals("null")) {
                        if (detailedCharacteristicsType.getAppliances().getAppliance() != null && !detailedCharacteristicsType.getAppliances().getAppliance().equals("null")) {
                            List<ApplianceEnum> appliance = detailedCharacteristicsType.getAppliances().getAppliance();
                            ArrayList<String> appliances = new ArrayList<>();
                            for (ApplianceEnum item : appliance) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    appliances.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setAppliances(appliances);
                        }
                    }
                    //建筑风格
                    if (detailedCharacteristicsType.getArchitectureStyle() != null && !detailedCharacteristicsType.getArchitectureStyle().equals("null")) {
                        String architectureStyle = detailedCharacteristicsType.getArchitectureStyle().getValue();
                        //detailedCharacteristics.setArchitecture_style(architectureStyle);
                    }

                    //制冷系统
                    if (detailedCharacteristicsType.getCoolingSystems() != null && !detailedCharacteristicsType.getCoolingSystems().equals("null")) {
                        if (detailedCharacteristicsType.getCoolingSystems().getCoolingSystem() != null && !detailedCharacteristicsType.getCoolingSystems().getCoolingSystem().equals("null")) {
                            List<CoolingSystemEnum> coolingSystem = detailedCharacteristicsType.getCoolingSystems().getCoolingSystem();
                            ArrayList<String> coolingSystems = new ArrayList<>();
                            for (CoolingSystemEnum item : coolingSystem) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    coolingSystems.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setCooling_systems(coolingSystems);
                        }
                    }

                    //室外装修
                    if (detailedCharacteristicsType.getExteriorTypes() != null && !detailedCharacteristicsType.getExteriorTypes().equals("null")) {
                        if (detailedCharacteristicsType.getExteriorTypes().getExteriorType() != null && !detailedCharacteristicsType.getExteriorTypes().getExteriorType().equals("null")) {
                            List<ExteriorFinishEnum> exteriorType = detailedCharacteristicsType.getExteriorTypes().getExteriorType();
                            ArrayList<String> exteriorTypes = new ArrayList<>();
                            for (ExteriorFinishEnum item : exteriorType) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    exteriorTypes.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setExterior_types(exteriorTypes);
                        }
                    }


                    //地板
                    if (detailedCharacteristicsType.getFloorCoverings() != null && !detailedCharacteristicsType.getFloorCoverings().equals("null")) {
                        if (detailedCharacteristicsType.getFloorCoverings().getFloorCovering() != null && !detailedCharacteristicsType.getFloorCoverings().getFloorCovering().equals("null")) {
                            List<FlooringMaterialEnum> floorCovering = detailedCharacteristicsType.getFloorCoverings().getFloorCovering();
                            ArrayList<String> floorCoverings = new ArrayList<>();
                            for (FlooringMaterialEnum item : floorCovering) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    floorCoverings.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setFloor_coverings(floorCoverings);
                        }
                    }

                    //供暖(燃料)
                    if (detailedCharacteristicsType.getHeatingFuels() != null && !detailedCharacteristicsType.getHeatingFuels().equals("null")) {
                        if (detailedCharacteristicsType.getHeatingFuels().getHeatingFuel() != null && !detailedCharacteristicsType.getHeatingFuels().getHeatingFuel().equals("null")) {
                            List<FuelEnum> heatingFuel = detailedCharacteristicsType.getHeatingFuels().getHeatingFuel();
                            ArrayList<String> heatingFuels = new ArrayList<>();
                            for (FuelEnum item : heatingFuel) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    heatingFuels.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setHeating_fuels(heatingFuels);
                        }
                    }

                    //供暖系统
                    if (detailedCharacteristicsType.getHeatingSystems() != null && !detailedCharacteristicsType.getHeatingSystems().equals("null")) {
                        if (detailedCharacteristicsType.getHeatingSystems().getHeatingSystem() != null && !detailedCharacteristicsType.getHeatingSystems().getHeatingSystem().equals("null")) {
                            List<HeatingSystemEnum> heatingSystem = detailedCharacteristicsType.getHeatingSystems().getHeatingSystem();
                            ArrayList<String> heatingSystems = new ArrayList<>();
                            for (HeatingSystemEnum item : heatingSystem) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    heatingSystems.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setHeating_systems(heatingSystems);
                        }
                    }
                    //车库
                    if (detailedCharacteristicsType.getParkingTypes() != null && !detailedCharacteristicsType.getParkingTypes().equals("null")) {
                        if (detailedCharacteristicsType.getParkingTypes().getParkingType() != null && !detailedCharacteristicsType.getParkingTypes().getParkingType().equals("null")) {
                            List<ParkingEnum> parkingType = detailedCharacteristicsType.getParkingTypes().getParkingType();
                            ArrayList<String> parkingTypes = new ArrayList<>();
                            for (ParkingEnum item : parkingType) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    parkingTypes.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setParking_types(parkingTypes);
                        }
                    }
                    //屋顶类型
                    if (detailedCharacteristicsType.getRoofTypes() != null && !detailedCharacteristicsType.getRoofTypes().equals("null")) {
                        if (detailedCharacteristicsType.getRoofTypes().getRoofType() != null && !detailedCharacteristicsType.getRoofTypes().getRoofType().equals("null")) {
                            List<RoofMaterialEnum> roofType = detailedCharacteristicsType.getRoofTypes().getRoofType();
                            ArrayList<String> roofTypes = new ArrayList<>();
                            for (RoofMaterialEnum item : roofType) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    roofTypes.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setRoof_types(roofTypes);
                        }
                    }

                    //房间
                    if (detailedCharacteristicsType.getRooms() != null && !detailedCharacteristicsType.getRooms().equals("null")) {
                        if (detailedCharacteristicsType.getRooms().getRoom() != null && !detailedCharacteristicsType.getRooms().getRoom().equals("null")) {
                            List<RoomCategoryEnum> room = detailedCharacteristicsType.getRooms().getRoom();
                            ArrayList<String> rooms = new ArrayList<>();
                            for (RoomCategoryEnum item : room) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    rooms.add(item.getValue());
                                }
                            }
                            //detailedCharacteristics.setRooms(rooms);
                        }
                    }

                    //视野类型
                    if (detailedCharacteristicsType.getViewTypes() != null && !detailedCharacteristicsType.getViewTypes().equals("null")) {
                        if (detailedCharacteristicsType.getViewTypes().getViewType() != null && !detailedCharacteristicsType.getViewTypes().getViewType().equals("null")) {
                            List<ViewEnum> viewType = detailedCharacteristicsType.getViewTypes().getViewType();
                            detailedCharacteristicsType.getViewTypes().getViewType();
                            ArrayList<String> viewTypes = new ArrayList<>();
                            for (ViewEnum item : viewType) {
                                if (!StringUtils.isEmpty(item.getValue())) {
                                    viewTypes.add(item.getValue());
                                }
                            }
                            detailedCharacteristics.setView_types(viewTypes);
                        }
                    }

                    detailedCharacteristics.setHas_attic(detailedCharacteristicsType.isHasAttic());
                    //detailedCharacteristics.setHas_barbecue_area(detailedCharacteristicsType.isHasBarbecueArea());
                    detailedCharacteristics.setHas_basement(detailedCharacteristicsType.isHasBasement());
                    //detailedCharacteristics.setBuilding_unit_count(detailedCharacteristicsType.getBuildingUnitCount());
                    detailedCharacteristics.setIs_cable_ready(detailedCharacteristicsType.isIsCableReady());
                    detailedCharacteristics.setHas_ceiling_fan(detailedCharacteristicsType.isHasCeilingFan());
                    detailedCharacteristics.setCondo_floor_num(detailedCharacteristicsType.getCondoFloorNum());
                    detailedCharacteristics.setHas_deck(detailedCharacteristicsType.isHasDeck());
                    detailedCharacteristics.setHas_disabled_access(detailedCharacteristicsType.isHasDisabledAccess());
                    detailedCharacteristics.setHas_dock(detailedCharacteristicsType.isHasDock());
                    detailedCharacteristics.setHas_doorman(detailedCharacteristicsType.isHasDoorman());
                    detailedCharacteristics.setHas_double_pane_windows(detailedCharacteristicsType.isHasDoublePaneWindows());
                    detailedCharacteristics.setHas_elevator(detailedCharacteristicsType.isHasElevator());
                    detailedCharacteristics.setHas_fireplace(detailedCharacteristicsType.isHasFireplace());
                    detailedCharacteristics.setHas_garden(detailedCharacteristicsType.isHasGarden());
                    //detailedCharacteristics.setHas_gated_entry(detailedCharacteristicsType.isHasGatedEntry());
                    detailedCharacteristics.setHas_greenhouse(detailedCharacteristicsType.isHasGreenhouse());
                    detailedCharacteristics.setHas_hot_tub_spa(detailedCharacteristicsType.isHasHotTubSpa());
                    detailedCharacteristics.setIntercom(detailedCharacteristicsType.isIntercom());
                    detailedCharacteristics.setHas_jetted_bath_tub(detailedCharacteristicsType.isHasJettedBathTub());
                    detailedCharacteristics.setHas_lawn(detailedCharacteristicsType.isHasLawn());
                    //detailedCharacteristics.setLegal_description(detailedCharacteristicsType.getLegalDescription());
                    //detailedCharacteristics.setHas_mother_in_law(detailedCharacteristicsType.isHasMotherInLaw());
                    detailedCharacteristics.setIs_new_construction(detailedCharacteristicsType.isIsNewConstruction());
                    detailedCharacteristics.setNum_floors(detailedCharacteristicsType.getNumFloors());
                    detailedCharacteristics.setNum_parking_spaces(detailedCharacteristicsType.getNumParkingSpaces());
                    detailedCharacteristics.setHas_patio(detailedCharacteristicsType.isHasPatio());
                    detailedCharacteristics.setHas_pond(detailedCharacteristicsType.isHasPond());
                    detailedCharacteristics.setHas_pool(detailedCharacteristicsType.isHasPool());
                    detailedCharacteristics.setHas_porch(detailedCharacteristicsType.isHasPorch());
                    // detailedCharacteristics.setRoom_count(detailedCharacteristicsType.getRoomCount());
                    detailedCharacteristics.setHas_rv_parking(detailedCharacteristicsType.isHasRVParking());
                    detailedCharacteristics.setHas_sauna(detailedCharacteristicsType.isHasSauna());
                    detailedCharacteristics.setHas_security_system(detailedCharacteristicsType.isHasSecuritySystem());
                    detailedCharacteristics.setHas_skylight(detailedCharacteristicsType.isHasSkylight());
                    detailedCharacteristics.setHas_sports_court(detailedCharacteristicsType.isHasSportsCourt());
                    detailedCharacteristics.setHas_sprinkler_system(detailedCharacteristicsType.isHasSprinklerSystem());
                    detailedCharacteristics.setHas_vaulted_ceiling(detailedCharacteristicsType.isHasVaultedCeiling());
                    detailedCharacteristics.setIs_water_front(detailedCharacteristicsType.isIsWaterfront());
                    detailedCharacteristics.setHas_wet_bar(detailedCharacteristicsType.isHasWetBar());
                    //detailedCharacteristics.setWhat_owner_loves(detailedCharacteristicsType.getWhatOwnerLoves());
                    detailedCharacteristics.setIs_wired(detailedCharacteristicsType.isIsWired());

                    return detailedCharacteristics;
                }
            }


        } catch (JSONException e) {
            e.printStackTrace();
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public HouseBasicInfo selectBasicInfo(String houseId) throws CustomException {
        HouseBasicInfo houseBasicInfo = new HouseBasicInfo();

        ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);
        if (listHub == null) {
            throw new CustomException(ResultCode.DATA_DOES_NOT_EXIST_OR_HAS_BEEN_DELETED);
        }
        houseBasicInfo.setAddress(listHub.getAddress());
        houseBasicInfo.setType(listHub.getPropertySubtype());

        houseBasicInfo.setBathrooms(listHub.getBathroomCount());
        houseBasicInfo.setBedrooms(listHub.getBedroomCount());

        houseBasicInfo.setCounty(listHub.getCounty());
        houseBasicInfo.setLiving_area(listHub.getLivingArea());
        houseBasicInfo.setLot_area(listHub.getLotSize());
        houseBasicInfo.setYear(listHub.getYearBuilt());

        houseBasicInfo.setFull_bathrooms(listHub.getFullBathroomCount());
        houseBasicInfo.setHalf_bathrooms(listHub.getHalfBathroomCount());
        houseBasicInfo.setQuarter_bathrooms(listHub.getThreeQuarterBathroomCount());
        houseBasicInfo.setMls_number(listHub.getMlsNumber());
        houseBasicInfo.setListing_price(listHub.getListPrice());
        Double average_price = null;

        if (listHub.getListPrice() != null && listHub.getListPrice() > 0) {
            if (listHub.getLivingArea() != null && listHub.getLivingArea() > 0) {
                average_price = listHub.getListPrice() / listHub.getLivingArea();
            }
        }

        houseBasicInfo.setAverage_price(DoubleUtils.format(average_price));
        String listingKey = listHub.getListingKey();
        if (!StringUtils.isEmpty(listingKey)) {
            String key = "json/" + listingKey + ".json";
            try {
                String json = downloadService.downloadJsonFromOSS(key);
                if (!StringUtils.isEmpty(json)) {
                    JSONObject jsonObject = JSONObject.fromObject(json);
                    //社区名称
                    if (jsonObject.get("location") != null && !jsonObject.get("location").equals("null")) {
                        JSONObject location = (JSONObject) jsonObject.get("location");
                        if (location.get("community") != null && !location.get("community").equals("null")) {
                            JSONObject community = (JSONObject) location.get("community");
                            if (community.get("communityName") != null && !community.get("communityName").equals("null")) {
                                String communityName = community.get("communityName").toString();
                                houseBasicInfo.setCommunity(communityName);
                            }
                        }
                    }
                    ObjectMapper mapper = new ObjectMapper();
                    //房源特征
                    if (jsonObject.get("detailedCharacteristics") != null && !jsonObject.get("detailedCharacteristics").equals("null")) {
                        JSONObject characteristics = (JSONObject) jsonObject.get("detailedCharacteristics");
                        if (characteristics != null && !characteristics.equals("null")) {
                            DetailedCharacteristicsType detailedCharacteristicsType = mapper.readValue(characteristics.toString(), DetailedCharacteristicsType.class);
                            //建筑风格
                            if (detailedCharacteristicsType.getArchitectureStyle() != null) {
                                houseBasicInfo.setStyle(detailedCharacteristicsType.getArchitectureStyle().getValue());
                            }
                        }
                    }

                    //税
                    if (jsonObject.get("taxes") != null && !jsonObject.get("taxes").equals("null")) {
                        JSONObject taxes = (JSONObject) jsonObject.get("taxes");
                        if (taxes != null && !taxes.equals("null")) {
                            ListingItemType.Taxes taxes_list = mapper.readValue(taxes.toString(), ListingItemType.Taxes.class);
                            final List<TaxType> taxs = taxes_list.getTax();
                            TaxType taxType = taxs.get(0);
                            if (taxType != null) {
                                if (taxType.getYear() != null && taxType.getAmount() != null) {
                                    houseBasicInfo.setProperty_tax(taxType.getYear().getYear() + ":" + taxType.getAmount().getValue());
                                }
                            }
                        }
                    }
                    //物业费
                    //Home Owner Assessments Fee
                    //额外费用
                    if (!StringUtils.isEmpty(jsonObject.get("expenses")) && !jsonObject.get("expenses").equals("null")) {
                        JSONObject expenses = (JSONObject) jsonObject.get("expenses");
                        if (expenses != null && !expenses.equals("null")) {
                            ListingItemType.Expenses expenses_list = mapper.readValue(expenses.toString(), ListingItemType.Expenses.class);
                            for (ExpensesType item : expenses_list.getExpense()) {
                                String value = item.getExpenseCategory().getValue();
                                if (!StringUtils.isEmpty(value) && value.equals("Home Owner Assessments Fee")) {
                                    //物业费
                                    houseBasicInfo.setHoa_fee(item.getExpenseValue().getValue() + "/" + item.getExpenseValue().getCurrencyPeriod());
                                    break;
                                }
                            }
                        }
                    }

                    if (!StringUtils.isEmpty(jsonObject.get("propertySubType")) && !jsonObject.get("propertySubType").equals("null")) {
                        JSONObject propertySubType = jsonObject.getJSONObject("propertySubType");
                        houseBasicInfo.setOriginalType(propertySubType.getString("value"));
                    }

                    //预估月租金
                    Double forecastRent = zillowService.getForecastRent(listHub.getZip(), listHub.getLivingArea());
                    houseBasicInfo.setRent_price(DoubleUtils.format(forecastRent));

                    return houseBasicInfo;
                }
            } catch (JSONException e) {
                e.printStackTrace();
                throw new CustomException(ResultCode.ERROR, e.getMessage());
            } catch (JsonParseException e) {
                e.printStackTrace();
                throw new CustomException(ResultCode.ERROR, e.getMessage());
            } catch (JsonMappingException e) {
                e.printStackTrace();
                throw new CustomException(ResultCode.ERROR, e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                throw new CustomException(ResultCode.ERROR, e.getMessage());
            }
        }
        return null;
    }

    @Override
    public ListHub selectDetailsByHouseId(String houseId) throws CustomException {
        ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);

        if (listHub == null || StringUtils.isEmpty(listHub.getListingKey())) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }
        String key = "json/" + listHub.getListingKey() + ".json";
        String json = downloadService.downloadJsonFromOSS(key);
        if (StringUtils.isEmpty(json)) {
            throw new CustomException(ResultCode.HOUSE_INEXISTENCE);
        }
        try {
            JSONObject dataJson = JSONObject.fromObject(json);
            ObjectMapper mapper = new ObjectMapper();
            //房源特征
            if (dataJson.get("detailedCharacteristics") != null && !dataJson.get("detailedCharacteristics").equals("null")) {
                JSONObject characteristics = (JSONObject) dataJson.get("detailedCharacteristics");
                if (characteristics != null && !characteristics.equals("null")) {
                    DetailedCharacteristicsType detailedCharacteristicsType = mapper.readValue(characteristics.toString(), DetailedCharacteristicsType.class);
                    listHub.setCharacteristics(detailedCharacteristicsType);
                }
            }

            //学校信息
            if (dataJson.get("location") != null && !dataJson.get("location").equals("null")) {
                JSONObject location = (JSONObject) dataJson.get("location");
                if (dataJson.get("community") != null && !dataJson.get("community").equals("null")) {
                    JSONObject community = (JSONObject) location.get("community");
                    if (dataJson.get("schools") != null && !dataJson.get("schools").equals("null")) {
                        JSONObject schools = (JSONObject) community.get("schools");
                        if (schools != null && !schools.equals("null")) {
                            Schools school = mapper.readValue(schools.toString(), Schools.class);
                            listHub.setSchools(school);
                        }
                    }
                }
            }

            //额外费用
            if (!StringUtils.isEmpty(dataJson.get("expenses")) && !dataJson.get("expenses").equals("null")) {
                JSONObject expenses = (JSONObject) dataJson.get("expenses");
                if (expenses != null && !expenses.equals("null")) {
                    ListingItemType.Expenses expenses1 = mapper.readValue(expenses.toString(), ListingItemType.Expenses.class);
                    listHub.setExpenses(expenses1);
                }
            }

            //预估月租金
            Double forecastRent = 0.0;
            if (!StringUtils.isEmpty(listHub.getZip())) {
                TimeValueItemResult timeValueItemResult = zillowService.get_Zip_ZriPerSqft_AllHomes(listHub.getZip());
                System.err.println("timeValueItemResult===>>" + timeValueItemResult.toString());
                if (timeValueItemResult != null) {
                    Double size = listHub.getLivingArea();
                    Double price = Double.valueOf(timeValueItemResult.getValue());
                    if (size != null && size > 0 && price != null && price > 0) {
                        forecastRent = size * price;
                    }
                }
            }
            listHub.setForecastRent(forecastRent);
            return listHub;
        } catch (IOException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.ERROR, e.getMessage());
        } catch (JSONException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.ERROR, e.getMessage());
        }
    }

    @Override
    public HouseDetailsResult selectDetailsByHouseIdOfApi(String houseId) throws CustomException {
        ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);

        HouseDetailsResult result = new HouseDetailsResult();

        if (listHub != null && !StringUtils.isEmpty(listHub.getListingKey())) {
            result.setAddress(listHub.getAddress());
            result.setPrice(listHub.getListPrice());
            result.setLat(listHub.getLatitude());
            result.setLng(listHub.getLongitude());
            result.setLivingArea(listHub.getLivingArea());
            result.setBedroomCount(listHub.getBedroomCount());
            result.setBathroomCount(listHub.getBathroomCount());

            String key = "json/" + listHub.getListingKey() + ".json";
            try {
                String json = downloadService.downloadJsonFromOSS(key);
                if (!StringUtils.isEmpty(json)) {
                    JSONObject dataJson = JSONObject.fromObject(json);
                    ObjectMapper mapper = new ObjectMapper();

                    ListingItemType listingItemType = mapper.readValue(dataJson.toString(), ListingItemType.class);

                    result.setDescription(listingItemType.getListingDescription());
                    result.setMls_name(listingItemType.getMlsName());
                    result.setMls_number(listingItemType.getMlsNumber());
                    result.setFull_bathrooms(listingItemType.getFullBathrooms());
                    result.setThree_quarter_bathrooms(listingItemType.getThreeQuarterBathrooms());
                    result.setHalf_bathrooms(listingItemType.getHalfBathrooms());
                    result.setOne_quarter_bathrooms(listingItemType.getOneQuarterBathrooms());
                    result.setPartial_bathrooms(listingItemType.getPartialBathrooms());


                    //建立者
                    final BusinessType businessType = listingItemType.getBuilder();
                    if (businessType != null) {
                        BuilderResult builder = new BuilderResult();

                        builder.setName(businessType.getName());
                        final Address address = businessType.getAddress();
                        List<String> addr = new ArrayList<>();

                        if (!StringUtils.isEmpty(address.getUnitNumber())) {
                            addr.add(StringUtils.toUpperCaseIndex(address.getUnitNumber().getValue()));
                        }

                        if (!StringUtils.isEmpty(address.getFullStreetAddress())) {
                            addr.add(StringUtils.toUpperCaseIndex(address.getFullStreetAddress()));
                        }

                        if (!StringUtils.isEmpty(address.getCity())) {
                            addr.add(StringUtils.toUpperCaseIndex(address.getCity().getValue()));
                        }

                        if (!StringUtils.isEmpty(address.getStateOrProvince())) {
                            addr.add(address.getStateOrProvince().getValue());
                        }
                        if (!StringUtils.isEmpty(address.getPostalCode())) {
                            addr.add(address.getPostalCode().getValue());
                        }
                        builder.setAddress(String.join(", ", addr));
                        builder.setEmail(businessType.getEmail());
                        builder.setPhone(businessType.getPhone());
                        builder.setUrl(businessType.getPhone());

                        result.setBuilder(builder);
                    }

                    //税
                    if (listingItemType.getTaxes() != null) {
                        List<TaxType> taxes = listingItemType.getTaxes().getTax();
                        if (taxes != null) {
                            List<TaxesResult> taxesResult = new ArrayList<>();
                            for (TaxType item : taxes) {
                                if (!StringUtils.isEmpty(item.getYear()) || !StringUtils.isEmpty(item.getAmount())) {
                                    TaxesResult taxe = new TaxesResult();
                                    if (item.getYear() != null) {
                                        taxe.setYear(item.getYear().getYear());
                                    }
                                    if (item.getAmount() != null) {
                                        taxe.setAmount(Double.valueOf(item.getAmount().getValue()));
                                    }
                                    if (!StringUtils.isEmpty(taxe.getYear()) || !StringUtils.isEmpty(taxe.getAmount())) {
                                        taxesResult.add(taxe);
                                    }
                                }
                            }
                            if (taxesResult != null && taxesResult.size() > 0) {
                                result.setTaxes(taxesResult);
                            }
                        }
                    }
                    //额外费用
                    if (listingItemType.getExpenses() != null) {
                        List<ExpensesType> expense = listingItemType.getExpenses().getExpense();
                        if (expense != null) {
                            List<ExpensesResult> expensesResults = new ArrayList<>();
                            for (ExpensesType item : expense) {
                                ExpensesResult expensesResult = new ExpensesResult();
                                if (item.getExpenseCategory() != null) {
                                    expensesResult.setType(item.getExpenseCategory().getValue());
                                }
                                if (item.getExpenseValue() != null) {
                                    expensesResult.setInterval(item.getExpenseValue().getCurrencyPeriod());
                                    expensesResult.setAmount(Double.valueOf(item.getExpenseValue().getValue()));
                                }
                                expensesResults.add(expensesResult);
                            }
                            if (expensesResults != null && expensesResults.size() > 0) {
                                result.setExpenses(expensesResults);
                            }
                        }
                    }

                    //房源特征
                    final DetailedCharacteristicsType detailedCharacteristics = listingItemType.getDetailedCharacteristics();
                    if (detailedCharacteristics != null) {
                        result.setHas_attic(detailedCharacteristics.isHasAttic());
                        result.setHas_barbecue_area(detailedCharacteristics.isHasBarbecueArea());
                        result.setHas_basement(detailedCharacteristics.isHasBasement());
                        result.setBuilding_unit_count(detailedCharacteristics.getBuildingUnitCount());

                        result.setIs_cable_ready(detailedCharacteristics.isIsCableReady());
                        result.setHas_ceiling_fan(detailedCharacteristics.isHasCeilingFan());
                        result.setCondo_floor_num(detailedCharacteristics.getCondoFloorNum());
                        result.setHas_deck(detailedCharacteristics.isHasDeck());
                        result.setHas_disabled_access(detailedCharacteristics.isHasDisabledAccess());
                        result.setHas_dock(detailedCharacteristics.isHasDock());
                        result.setHas_doorman(detailedCharacteristics.isHasDoorman());
                        result.setHas_double_pane_windows(detailedCharacteristics.isHasDoublePaneWindows());
                        result.setHas_elevator(detailedCharacteristics.isHasElevator());
                        result.setHas_fireplace(detailedCharacteristics.isHasFireplace());
                        result.setHas_garden(detailedCharacteristics.isHasGarden());
                        result.setHas_gated_entry(detailedCharacteristics.isHasGatedEntry());
                        result.setHas_greenhouse(detailedCharacteristics.isHasGreenhouse());
                        result.setHas_hot_tub_spa(detailedCharacteristics.isHasHotTubSpa());
                        result.setIntercom(detailedCharacteristics.isIntercom());
                        result.setHas_jetted_bath_tub(detailedCharacteristics.isHasJettedBathTub());
                        result.setHas_lawn(detailedCharacteristics.isHasLawn());
                        result.setHas_mother_in_law(detailedCharacteristics.isHasMotherInLaw());
                        result.setIs_new_construction(detailedCharacteristics.isIsNewConstruction());
                        result.setNum_floors(detailedCharacteristics.getNumFloors());
                        result.setNum_parking_spaces(detailedCharacteristics.getNumParkingSpaces());
                        result.setHas_patio(detailedCharacteristics.isHasPatio());
                        result.setHas_pond(detailedCharacteristics.isHasPond());
                        result.setHas_pool(detailedCharacteristics.isHasPool());
                        result.setHas_porch(detailedCharacteristics.isHasPorch());
                        result.setHas_rv_parking(detailedCharacteristics.isHasRVParking());
                        result.setHas_sauna(detailedCharacteristics.isHasSauna());
                        result.setHas_security_system(detailedCharacteristics.isHasSecuritySystem());
                        result.setHas_skylight(detailedCharacteristics.isHasSkylight());
                        result.setHas_sports_court(detailedCharacteristics.isHasSportsCourt());
                        result.setHas_sprinkler_system(detailedCharacteristics.isHasSprinklerSystem());
                        result.setHas_vaulted_ceiling(detailedCharacteristics.isHasVaultedCeiling());
                        result.setIs_waterfront(detailedCharacteristics.isIsWaterfront());
                        result.setHas_wet_bar(detailedCharacteristics.isHasWetBar());
                        result.setIs_wired(detailedCharacteristics.isIsWired());

                        if (detailedCharacteristics.getAppliances() != null) {
                            List<ApplianceEnum> appliances_list = detailedCharacteristics.getAppliances().getAppliance();
                            if (appliances_list != null) {
                                List<String> items = new ArrayList<>();
                                for (ApplianceEnum item : appliances_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setAppliances(items);
                                }
                            }
                        }

                        if (detailedCharacteristics.getCoolingSystems() != null) {
                            List<CoolingSystemEnum> coolingSystem_list = detailedCharacteristics.getCoolingSystems().getCoolingSystem();
                            if (coolingSystem_list != null) {
                                List<String> items = new ArrayList<>();
                                for (CoolingSystemEnum item : coolingSystem_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setCooling_systems(items);
                                }
                            }
                        }

                        if (detailedCharacteristics.getExteriorTypes() != null) {
                            List<ExteriorFinishEnum> exteriorType_list = detailedCharacteristics.getExteriorTypes().getExteriorType();
                            if (exteriorType_list != null) {
                                List<String> items = new ArrayList<>();
                                for (ExteriorFinishEnum item : exteriorType_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setExterior_types(items);
                                }
                            }
                        }
                        if (detailedCharacteristics.getFloorCoverings() != null) {
                            List<FlooringMaterialEnum> floorCovering_list = detailedCharacteristics.getFloorCoverings().getFloorCovering();
                            if (floorCovering_list != null) {
                                List<String> items = new ArrayList<>();
                                for (FlooringMaterialEnum item : floorCovering_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setFloor_coverings(items);
                                }
                            }
                        }

                        if (detailedCharacteristics.getHeatingFuels() != null) {
                            List<FuelEnum> heatingFuel_list = detailedCharacteristics.getHeatingFuels().getHeatingFuel();
                            if (heatingFuel_list != null) {
                                List<String> items = new ArrayList<>();
                                for (FuelEnum item : heatingFuel_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setHeating_fuels(items);
                                }
                            }
                        }

                        if (detailedCharacteristics.getHeatingSystems() != null) {
                            List<HeatingSystemEnum> heatingSystem_list = detailedCharacteristics.getHeatingSystems().getHeatingSystem();
                            if (heatingSystem_list != null) {
                                List<String> items = new ArrayList<>();
                                for (HeatingSystemEnum item : heatingSystem_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setHeating_systems(items);
                                }
                            }
                        }

                        if (detailedCharacteristics.getParkingTypes() != null) {
                            List<ParkingEnum> parkingType_list = detailedCharacteristics.getParkingTypes().getParkingType();
                            if (parkingType_list != null) {
                                List<String> items = new ArrayList<>();
                                for (ParkingEnum item : parkingType_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setParking_types(items);
                                }
                            }
                        }
                        if (detailedCharacteristics.getRoofTypes() != null) {
                            List<RoofMaterialEnum> roofType_list = detailedCharacteristics.getRoofTypes().getRoofType();
                            if (roofType_list != null) {
                                List<String> items = new ArrayList<>();
                                for (RoofMaterialEnum item : roofType_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setRoof_types(items);
                                }
                            }
                        }

                        if (detailedCharacteristics.getViewTypes() != null) {
                            List<ViewEnum> viewType_list = detailedCharacteristics.getViewTypes().getViewType();
                            if (viewType_list != null) {
                                List<String> items = new ArrayList<>();
                                for (ViewEnum item : viewType_list) {
                                    if (!StringUtils.isEmpty(item.getValue())) {
                                        items.add(item.getValue());
                                    }
                                }
                                if (items != null && items.size() > 0) {
                                    result.setView_types(items);
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @Override
    public ProviderResult selectProviderByHouseId(String houseId) throws CustomException {
        ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);

        ProviderResult result = new ProviderResult();
        if (listHub != null && !StringUtils.isEmpty(listHub.getListingKey())) {
            String key = "json/" + listHub.getListingKey() + ".json";
            try {
                String json = downloadService.downloadJsonFromOSS(key);
                if (!StringUtils.isEmpty(json)) {
                    JSONObject dataJson = JSONObject.fromObject(json);
                    ObjectMapper mapper = new ObjectMapper();
                    ListingItemType listingItemType = mapper.readValue(dataJson.toString(), ListingItemType.class);
                    BusinessType brokerage = listingItemType.getBrokerage();
                    if (brokerage != null) {
                        result.setName(brokerage.getName());
                        result.setPhone(brokerage.getPhone());
                        result.setEmail(brokerage.getEmail());
                        result.setUrl(brokerage.getWebsiteURL());
                        result.setAddress(AddressUtils.getAddress(brokerage.getAddress()));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @Override
    public DTOStatsResult selectStatsOfApi(String houseId) throws CustomException {

        DTOStatsResult stats = new DTOStatsResult();
        Long open_time = System.currentTimeMillis();
        try {
            ListHub listHub = listHubMapper.selectByPrimaryKey(houseId);
            String zipcode = listHub.getZip();
            if (StringUtils.isEmpty(zipcode)) {
                throw new CustomException(ResultCode.NO_DATA_WAS_FOUND);
            }
            Double price = listHub.getListPrice(); //价格
            Double area = listHub.getLivingArea(); //面积

            TruliaData truliaData = truliaDataService.selectByZipcode(zipcode);
            CityData cityData = cityDataService.selectByZipcode(zipcode);

            //TimeSeriesDataHomeValueForecast homeValueForecast = timeSeriesDataHomeValueForecastService.selectByZipcode(zipcode);
            Zip zip = zipService.selectByPrimaryKey(zipcode);
            String key_homeValueForecast = "zillow/AllRegionsForePublic/" + zip.getState().toLowerCase() + "_zip_" + zip.getZipcode() + ".json";
            Double homeValueForecast = 0.0;
            if (!StringUtils.isEmpty(key_homeValueForecast)) {
                String homeValueForecast_json = downloadService.downloadJsonFromOSS(key_homeValueForecast);
                if (!StringUtils.isEmpty(homeValueForecast_json)) {
                    com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(homeValueForecast_json);
                    System.err.println("jsonObject:" + jsonObject.toString());
                    if (!StringUtils.isEmpty(jsonObject)) {
                        String forecastYoYPctChange = jsonObject.getString("ForecastYoYPctChange");
                        System.err.println("forecastYoYPctChange:" + forecastYoYPctChange.toString());
                        if (!StringUtils.isEmpty(forecastYoYPctChange)) {
                            homeValueForecast = Double.valueOf(forecastYoYPctChange);
                        }
                    }
                }
            }

            Date etime = DateUtils.DateToDateline(new Date());
            Date btime = DateUtils.DateToDateline(DateUtils.addYear(etime, -10));
            Date btime20 = DateUtils.DateToDateline(DateUtils.addYear(etime, -20));
            //List<TimeSeriesDataAllHomes> timeSeriesDataAllHomes_list = timeSeriesDataAllHomesService.findByZipcodeAndTimeBetweenOrderByTimeAsc(zipcode, btime20, etime);
            String key_Zip_Zhvi_AllHomes = "zillow/Zip_Zhvi_AllHomes/" + zipcode + ".json";
            List<TimeValueItemResult> timeSeriesDataAllHomes_list = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_AllHomes, "20");

            //List<TimeSeriesDataAllRentByZip> TimeSeriesDataAllRentByZip_rents = timeSeriesDataAllRentByZipService.findByZipcodeAndTimeBetweenOrderByTimeAsc(zipcode, btime, etime);
            //AllRentByZip ===>>Zip_Zri_AllHomesPlusMultifamily
            String key_Zip_Zri_AllHomesPlusMultifamily = "zillow/Zip_Zri_AllHomesPlusMultifamily/" + zipcode + ".json";
            List<TimeValueItemResult> TimeSeriesDataAllRentByZip_rents = downloadService.downloadTimeValuesFromOSS(key_Zip_Zri_AllHomesPlusMultifamily, "10");

            //List<TimeSeriesDataAllHomes> TimeSeriesDataAllHomes_homes = timeSeriesDataAllHomesService.findByZipcodeAndTimeBetweenOrderByTimeAsc(zipcode, btime, etime);
            List<TimeValueItemResult> TimeSeriesDataAllHomes_homes = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_AllHomes, "10");

            List<DTOTimeSeriesItem> mon = mon(timeSeriesDataAllHomes_list);
            stats.setPrice_mom(mon);

            List<DTOTimeSeriesItem> yoy = yoy(timeSeriesDataAllHomes_list);
            stats.setPrice_yoy(yoy);

            stats.setCommute_index(CommuteIndex(truliaData));
            stats.setMedian_sales_price_ratio(getHousePricesCompareWithAverage(price, truliaData));
            stats.setMedian_sales_price_sqft_ratio(getHousePricesCompareWithAverageSQFT(price, area, truliaData));
            stats.setArea_price_forecast(getHomeValueForecast(homeValueForecast, truliaData));
            stats.setPrice_forecast(getCurrentHomeValueForecast(homeValueForecast, price));
            stats.setDemographics(getPopulationRatio(cityData));
            stats.setEducation(getEducationRatio(truliaData, cityData));
            stats.setUnemployment(getUnemployedRatio(cityData, zip));
            stats.setAffordability(getAffordability(zip));
            stats.setUs_state_price_trend(getStateUSHomePriceTrend(zip));

            List<DTOTimeSeriesItem> rentalYield = getRentalYield(TimeSeriesDataAllRentByZip_rents, TimeSeriesDataAllHomes_homes);
            stats.setRental_yield_trend(rentalYield);

            List<DTOTimeSeriesItem> medianRent = getMedianRent(TimeSeriesDataAllRentByZip_rents);
            stats.setMedian_rent_trend(medianRent);

            stats.setPrice_rent_ratio(getPricesRents(TimeSeriesDataAllRentByZip_rents, TimeSeriesDataAllHomes_homes));
            stats.setSfr_condo_price_trend(getSFRCondo(zipcode));
            stats.setDtoIncome(getAverageHouseHoldIncome(truliaData));

            List<DTOTimeSeriesItem> rent = getRent(zipcode);
            stats.setRent(rent);

            stats.setBedroom_price_trend(getBedRoom(zipcode));

        } catch (Exception e) {
            e.printStackTrace();
        }
        Long close_time = System.currentTimeMillis();

        System.err.println("=============time:" + (close_time - open_time));
        return stats;

    }

    @Override
    public boolean selectExistByHouseId(String houseId) throws CustomException {
        if (listHubMapper.selectExistsByPrimaryKey(houseId) > 0) {
            return true;
        }
        return false;
    }

    public void createJson(String listingKey, String unitNumber, String fullStreetAddress, String city, String state, String county, String zip,
                           Double listPrice, String listingCategory, String listingStatus, Date listingDate, String listingTitle, String listingDescription,
                           Integer bedroomCount, Integer bathroomCount, Integer fullBathroomCount, Integer threeQuarterBathroomCount, Integer halfBathroomCount,
                           Integer oneQuarterBathroomCount, String propertyType, String propertySubtype, String mlsId, String mlsName, String mlsNumber,
                           Double livingArea, Double lotSize, Integer yearBuilt, String builderName, Double latitude, Double longitude, String parcelId) {
        try {

            System.err.println("===========生成json文件===========");
            ListingItemType listingItemType = new ListingItemType();
            Address address = new Address();

            if (!StringUtils.isEmpty(city)) {
                CityType cityType = new CityType();
                cityType.setValue(city);
                address.setCity(cityType);
            }

            if (!StringUtils.isEmpty(zip)) {
                PostalCodeType postalCodeType = new PostalCodeType();
                postalCodeType.setValue(zip);
                address.setPostalCode(postalCodeType);
            }

            if (!StringUtils.isEmpty(state)) {
                StateOrProvinceType stateOrProvinceType = new StateOrProvinceType();
                stateOrProvinceType.setValue(state);
                address.setStateOrProvince(stateOrProvinceType);
            }

            address.setFullStreetAddress(fullStreetAddress);

            if (!StringUtils.isEmpty(unitNumber)) {
                UnitNumberType unitNumberType = new UnitNumberType();
                unitNumberType.setValue(unitNumber);
                address.setUnitNumber(unitNumberType);
            }

            if (!StringUtils.isEmpty(county)) {
                CountryType countryType = new CountryType();
                countryType.setValue(county);
                address.setCountry(countryType);
            }

            listingItemType.setAddress(address);

            if (!StringUtils.isEmpty(listPrice)) {
                PriceWithOptionalFrequency priceWithOptionalFrequency = new PriceWithOptionalFrequency();
                priceWithOptionalFrequency.setValue(String.valueOf(listPrice));
                listingItemType.setListPrice(priceWithOptionalFrequency);
            }

            if (listingStatus.equals("Active")) {
                listingItemType.setListingStatus(ListingStatusEnum.ACTIVE);
            } else if (listingStatus.equals("Cancelled")) {
                listingItemType.setListingStatus(ListingStatusEnum.CANCELLED);
            } else if (listingStatus.equals("Closed")) {
                listingItemType.setListingStatus(ListingStatusEnum.CLOSED);
            } else if (listingStatus.equals("Expired")) {
                listingItemType.setListingStatus(ListingStatusEnum.EXPIRED);
            } else if (listingStatus.equals("Pending")) {
                listingItemType.setListingStatus(ListingStatusEnum.PENDING);
            } else if (listingStatus.equals("Withdrawn")) {
                listingItemType.setListingStatus(ListingStatusEnum.WITHDRAWN);
            }

            if (listingCategory.equals("Purchase")) {
                listingItemType.setListingCategory(ListingCategoryEnum.PURCHASE);
            } else if (listingCategory.equals("Lease")) {
                listingItemType.setListingCategory(ListingCategoryEnum.LEASE);
            } else if (listingCategory.equals("Rent")) {
                listingItemType.setListingCategory(ListingCategoryEnum.RENT);
            }

            if (!StringUtils.isEmpty(listingDate))
                listingItemType.setListingDate(DateUtils.dateToXmlDate(listingDate));

            listingItemType.setListingTitle(listingTitle);
            listingItemType.setListingDescription(listingDescription);
            if (!StringUtils.isEmpty(bedroomCount))
                listingItemType.setBedrooms(String.valueOf(bedroomCount));
            if (!StringUtils.isEmpty(bathroomCount))
                listingItemType.setBathrooms(String.valueOf(bathroomCount));
            if (!StringUtils.isEmpty(fullBathroomCount))
                listingItemType.setFullBathrooms(BigInteger.valueOf(fullBathroomCount));
            if (!StringUtils.isEmpty(halfBathroomCount))
                listingItemType.setHalfBathrooms(BigInteger.valueOf(halfBathroomCount));
            if (!StringUtils.isEmpty(threeQuarterBathroomCount))
                listingItemType.setThreeQuarterBathrooms(BigInteger.valueOf(threeQuarterBathroomCount));
            if (!StringUtils.isEmpty(oneQuarterBathroomCount))
                listingItemType.setOneQuarterBathrooms(BigInteger.valueOf(oneQuarterBathroomCount));

            if (!StringUtils.isEmpty(propertyType)) {
                PropertyTypeEnum propertyTypeEnum = new PropertyTypeEnum();
                propertyTypeEnum.setValue(propertyType);
                listingItemType.setPropertyType(propertyTypeEnum);
            }

            if (!StringUtils.isEmpty(propertySubtype)) {
                PropertySubTypeEnum propertySubTypeEnum = new PropertySubTypeEnum();
                propertySubTypeEnum.setValue(propertySubtype);
                listingItemType.setPropertySubType(propertySubTypeEnum);
            }

            listingItemType.setMlsId(mlsId);
            listingItemType.setMlsName(mlsName);
            listingItemType.setMlsNumber(mlsNumber);

            if (!StringUtils.isEmpty(livingArea)) {
                Area area_LivingArea = new Area();
                area_LivingArea.setValue(String.valueOf(livingArea));
                listingItemType.setLivingArea(area_LivingArea);
            }

            if (!StringUtils.isEmpty(lotSize)) {
                Area area_LotSize = new Area();
                area_LotSize.setValue(String.valueOf(lotSize));
                listingItemType.setLotSize(area_LotSize);
            }

            if (!StringUtils.isEmpty(yearBuilt)) {
                Date year = DateUtils.parseDate(String.valueOf(yearBuilt), "yyyy");
                listingItemType.setYearBuilt(DateUtils.dateToXmlDate(year));
            }


            if (!StringUtils.isEmpty(builderName)) {
                BusinessType businessType = new BusinessType();
                businessType.setName(builderName);
                listingItemType.setBuilder(businessType);
            }

            if (!StringUtils.isEmpty(parcelId) || !StringUtils.isEmpty(latitude) || !StringUtils.isEmpty(longitude)) {
                LocationType location = new LocationType();
                if (!StringUtils.isEmpty(parcelId))
                    location.setParcelId(parcelId);
                if (!StringUtils.isEmpty(latitude))
                    location.setLatitude(String.valueOf(latitude));
                if (!StringUtils.isEmpty(longitude))
                    location.setLongitude(String.valueOf(longitude));

                listingItemType.setLocation(location);
            }

            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(listingItemType);

            String fileName = "/alldata/listhub/json/" + listingKey + ".json";
            //生成json 文件，如果已经存在，删除后再创建，不存在直接创建
            if (!FileUtils.createJsonFile(json, fileName)) {
                System.err.println("文件生成失败：" + fileName);
            } else {
                upload(fileName);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public void upload(String filePath) {
        OSSClient ossClient = new OSSClient(
                ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()
        );
        String eTag = ossService.uploadObject2OSS(ossClient, new File(filePath), ossConfig.getBacketName(), "json");

        System.err.println("======================upload json ================" + filePath + "=========================");
        if (!StringUtils.isEmpty(eTag)) {
            //删除本地文件
            FileUtils.deleteFile(new File(filePath));
        }
    }


    /**
     * 房价环比增长率
     *
     * @param list
     * @return
     */
    public List<DTOTimeSeriesItem> mon(List<TimeValueItemResult> list) {
        if (list == null || list.size() == 0) {
            return null;
        }
        List<DTOTimeSeriesItem> moms = new ArrayList<>();
        try {

//            Date etime = new Date();
//            Date btime = DateUtils.addYear(etime, -10);
//            List<TimeSeriesDataAllHomes> list = timeSeriesDataAllHomesService.findByZipcodeAndTimeBetweenOrderByTimeAsc(zipcode, DateUtils.DateToDateline(btime), DateUtils.DateToDateline(etime));
            for (int i = 0; i < list.size(); i++) {
                Date current_time = DateUtils.StrToDate(list.get(i).getTime(), "yyyy-MM");
                Double current_value = Double.valueOf(list.get(i).getValue()); //当前月的值
                Date last_month = null;
                Double last_value = 0.0;
                if (i > 0) {
                    last_month = DateUtils.StrToDate(list.get(i - 1).getTime(), "yyyy-MM");
                    last_value = Double.valueOf(list.get(i - 1).getValue()); //上月的值
                    Double ratio = 0.0;
                    if (last_value != 0) {
                        //房价环比增长率(moms)  环比增长率=(本期数-上期数)/上期数×100%。
                        ratio = (current_value - last_value) / last_value * 100;
                    }
                    DTOTimeSeriesItem mom = new DTOTimeSeriesItem();
                    mom.setTime(DateUtils.DateToStr(current_time, "yyyy-MM"));
                    mom.setValue(ratio);
                    moms.add(mom);
                }
            }
            Collections.reverse(moms);
            if (moms.size() > 120) {
                moms = moms.subList(0, 120);
            }
            Collections.reverse(moms);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return moms;
    }

    /**
     * 房价同比增长率
     *
     * @param list
     * @return
     */
    public List<DTOTimeSeriesItem> yoy(List<TimeValueItemResult> list) {
        if (list == null || list.size() == 0) {
            return null;
        }
        List<DTOTimeSeriesItem> yoys = new ArrayList<>();
        try {
            //房价同比增长率(yoys)  同比增长率=(本期数-同期数)÷同期数×100%
            //Date etime = new Date();
            //Date btime = DateUtils.addYear(etime, -20);
            // List<TimeSeriesDataAllHomes> list = timeSeriesDataAllHomesService.findByZipcodeAndTimeBetweenOrderByTimeAsc(zipcode, DateUtils.DateToDateline(btime), DateUtils.DateToDateline(etime));
            for (int i = 0; i < list.size(); i++) {
                Date current_time = DateUtils.StrToDate(list.get(i).getTime(), "yyyy-MM");
                Double current_value = Double.valueOf(list.get(i).getValue());
                Date last_month = null;
                Double last_value = 0.0;
                if (i > 12) {
                    last_month = DateUtils.StrToDate(list.get(i - 12).getTime(), "yyyy-MM");
                    last_value = Double.valueOf(list.get(i - 12).getValue());
                    Double ratio = 0.0;
                    if (last_value != 0) {
                        ratio = (current_value - last_value) / last_value * 100;
                    }
                    DTOTimeSeriesItem yoy = new DTOTimeSeriesItem();
                    yoy.setTime(DateUtils.DateToStr(current_time, "yyyy-MM"));
                    yoy.setValue(ratio);
                    yoys.add(yoy);
                }
            }
            Collections.reverse(yoys);
            if (yoys.size() > 120) {
                yoys = yoys.subList(0, 120);
            }
            Collections.reverse(yoys);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return yoys;
    }

    /**
     * 通勤指数
     *
     * @param truliaData
     * @return
     */
    public DTOCommuteIndex CommuteIndex(TruliaData truliaData) {
        DTOCommuteIndex commuteIndex = new DTOCommuteIndex();
        if (truliaData != null) {
            //骑车通勤比例%
            commuteIndex.setBike(truliaData.getCommuteBike());
            //驾车通勤比例%
            commuteIndex.setCar(truliaData.getCommuteCar());
            //步行通勤比例%
            commuteIndex.setFoot(truliaData.getCommuteFoot());
            //公交通勤比例%
            commuteIndex.setTransit(truliaData.getCommuteTransit());
        }
        return commuteIndex;
    }

    /**
     * 房源价值/zipcode均价(此房源价格与附近价格对比)
     *
     * @param housePrice
     * @param truliaData
     * @return
     */
    public DTOMedianSalesPrice getHousePricesCompareWithAverage(Double housePrice, TruliaData truliaData) {
        DTOMedianSalesPrice priceRatio = new DTOMedianSalesPrice();
        if (!StringUtils.isEmpty(housePrice) && truliaData != null) {
            Double median_sales_price = truliaData.getMedianSalesPrice();  //房产售价中位数
            Double ratio = 0.00;
            if (median_sales_price != null && median_sales_price != 0) {
                ratio = housePrice / median_sales_price;
            }
            priceRatio.setPrice(housePrice);
            priceRatio.setMedian_sales_price(median_sales_price);
            priceRatio.setRatio(ratio);
        }
        return priceRatio;
    }

    /**
     * 房源每平方英尺均价/zipcode每平方英尺均价
     *
     * @param price
     * @param area
     * @param truliaData
     * @return
     */
    public DTOMedianSalesPrice getHousePricesCompareWithAverageSQFT(Double price, Double area, TruliaData truliaData) {
        DTOMedianSalesPrice housePrice_medianSalesPrice_ratio = new DTOMedianSalesPrice();
        Double pricePerSqFt = null;
        if (area != null || area > 0) {
            pricePerSqFt = Double.valueOf(price / area); // 房产每平方英尺单价
            housePrice_medianSalesPrice_ratio.setPrice(pricePerSqFt);
        }
        if (truliaData != null) {
            Double city_pricePerSqFt = truliaData.getPricePerSqft(); //每平方英尺单价
            Double ratio = Double.valueOf(0);
            if (city_pricePerSqFt != null && city_pricePerSqFt != 0) {
                ratio = pricePerSqFt / city_pricePerSqFt;
            }
            housePrice_medianSalesPrice_ratio.setMedian_sales_price(city_pricePerSqFt);
            housePrice_medianSalesPrice_ratio.setRatio(ratio);
        }
        return housePrice_medianSalesPrice_ratio;
    }

    /**
     * zipcode 房价预测
     *
     * @param homeValueForecast
     * @return
     */

    /**
     * zipcode 房价预测
     *
     * @param rise       增浮率
     * @param truliaData
     * @return
     */
    public DTOPriceForecast getHomeValueForecast(Double rise, TruliaData truliaData) {
        DTOPriceForecast priceForecast = new DTOPriceForecast();
        priceForecast.rise = rise;
        if (truliaData != null) {
            Double price = truliaData.getMedianSalesPrice();
            priceForecast.current_price = price;
            if (rise == null || price == null) {
                Double forecastPrice = price * (1 + rise / 100);
                priceForecast.forecast_price = forecastPrice;
            }
        }

        return priceForecast;
    }

    /**
     * 当前房源房价预测
     *
     * @param rise  增浮率
     * @param price
     * @return
     */
    public DTOPriceForecast getCurrentHomeValueForecast(Double rise, Double price) {
        DTOPriceForecast priceForecast = new DTOPriceForecast();
        Double forecastPrice = price * (1 + rise / 100);
        priceForecast.current_price = price;
        priceForecast.forecast_price = forecastPrice;
        priceForecast.rise = rise;
        return priceForecast;
    }

    /**
     * 族裔比例
     *
     * @param cityData
     * @return
     */
    public DTOPopulationRatio getPopulationRatio(CityData cityData) {
        DTOPopulationRatio populationRatio = new DTOPopulationRatio();
        if (cityData == null) {
            return null;
        }
        //===族裔比例===
        Double indian = cityData.getPopulationAmericanIndian();
        Double black = cityData.getPopulationBlack();
        Double hispanic = cityData.getPopulationHispanic();
        Double islander = cityData.getPopulationIslander();
        Double white = cityData.getPopulationWhite();

        populationRatio.setIndian(indian); //美属印第安人人口
        populationRatio.setBlack(black); //非裔人口
        populationRatio.setHispanic(hispanic); //拉丁裔人口
        populationRatio.setIslander(islander); //太平洋及岛屿人口
        populationRatio.setWhite(white); //白人人口

        return populationRatio;
    }

    /**
     * 大学以上教育比例
     *
     * @param truliaData
     * @param cityData
     * @return
     */
    public DTOEducation getEducationRatio(TruliaData truliaData, CityData cityData) {
        DTOEducation education = new DTOEducation();
        //全美大学以上教育比例
        education.setUs(usaConfig.getUniversity_ratio());

        if (truliaData != null) {
            //本地大学以上教育比例
            education.setLocal(truliaData.getDemoCollegeEducated());
        }
        if (cityData != null) {
            //州大学以上教育比例
            education.setState(cityData.getPrivateUndergraduateCollegesState());
        }
        return education;
    }

    /**
     * 失业率
     *
     * @param cityData
     * @param zip
     * @return
     */
    public DTOUnemploymentRate getUnemployedRatio(CityData cityData, Zip zip) {
        DTOUnemploymentRate unemploymentRate = new DTOUnemploymentRate();
        //全美失业率
        unemploymentRate.setUs(usaConfig.getUnemployed());
        if (cityData != null) {
            //本地失业率
            unemploymentRate.setLocal(cityData.getUnemployed());
        }

        if (zip != null) {
            String state = zip.getState();
            Double state_unemployed_rate = unemploymentService.selectRateByUnemployment(1, state);
            //州失业率
            if (state_unemployed_rate != null) {
                unemploymentRate.setState(state_unemployed_rate);
            }
        }

        return unemploymentRate;
    }

    /**
     * 购房指数（压力）
     *
     * @param zip
     * @return
     */
    public DTOAffordability getAffordability(Zip zip) {
        if (zip == null) {
            return null;
        }
        DTOAffordability affordability = new DTOAffordability();

        String metro = zip.getMetro();
        String price_to_income = "zillow/Affordability_Wide_Public/" + StringUtils.replaceBlankAndComma(metro) + "_price_to_income.json";
        String mortgage_affordability = "zillow/Affordability_Wide_Public/" + StringUtils.replaceBlankAndComma(metro) + "_mortgage_affordability.json";
        String rent_affordability = "zillow/Affordability_Wide_Public/" + StringUtils.replaceBlankAndComma(metro) + "_rent_affordability.json";

        List<TimeValueItemResult> price_to_income_result = downloadService.downloadTimeValuesFromOSS(price_to_income);
        List<TimeValueItemResult> mortgage_affordability_result = downloadService.downloadTimeValuesFromOSS(mortgage_affordability);
        List<TimeValueItemResult> rent_affordability_result = downloadService.downloadTimeValuesFromOSS(rent_affordability);

        affordability.price_to_income = Double.valueOf(price_to_income_result.get(price_to_income_result.size() - 1).getValue());
        affordability.mortgage_affordability = Double.valueOf(mortgage_affordability_result.get(mortgage_affordability_result.size() - 1).getValue());
        affordability.rent_affordability = Double.valueOf(rent_affordability_result.get(rent_affordability_result.size() - 1).getValue());

        return affordability;
    }

    /**
     * state/US房源价格走势 （state/US房价变化）
     *
     * @param zip
     * @return
     */
    public DTOStateMetroResult getStateUSHomePriceTrend(Zip zip) {
        DTOStateMetroResult stateUSResult = new DTOStateMetroResult();
        try {
            if (zip != null) {
                String state = zip.getState();
                String metro = zip.getMetro();
                String time = "10";
                if (state.length() < 3) {
                    state = StringUtils.stateAbbreviationToAll(state);
                }

                String state_key = "zillow/State_Zhvi_AllHomes/" + state.toLowerCase() + ".json";
                String metro_key = "zillow/Metro_Zhvi_AllHomes/" + StringUtils.replaceBlankAndComma(metro) + ".json";

                List<TimeValueItemResult> timeValueItemResults_state = downloadService.downloadTimeValuesFromOSS(state_key, time);
                List<TimeValueItemResult> timeValueItemResults_metro = downloadService.downloadTimeValuesFromOSS(metro_key, time);

                List<DTOTimeSeriesItem> state_items = new ArrayList<>();
                List<DTOTimeSeriesItem> metro_items = new ArrayList<>();

//                if (timeValueItemResults_state != null && timeValueItemResults_state.size() > 0) {
//                    for (TimeValueItemResult item : timeValueItemResults_state) {
//                        if (item.getValue() != null) {
//                            DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
//                            timeSeriesItem.setTime(item.getTime());
//                            timeSeriesItem.setValue(Double.valueOf(item.getValue()));
//                            state_items.add(timeSeriesItem);
//                        }
//                    }
//                    stateUSResult.setState(state_items);
//                }

//                if (timeValueItemResults_metro != null && timeValueItemResults_metro.size() > 0) {
//                    for (TimeValueItemResult item : timeValueItemResults_metro) {
//                        if (item.getValue() != null) {
//                            DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
//                            timeSeriesItem.setTime(item.getTime());
//                            timeSeriesItem.setValue(Double.valueOf(item.getValue()));
//                            metro_items.add(timeSeriesItem);
//                        }
//                    }
//                    stateUSResult.setMetro(metro_items);
//                }

                stateUSResult.setState(timeSeriesDataToTimeSeriesItem2(timeValueItemResults_state));
                stateUSResult.setMetro(timeSeriesDataToTimeSeriesItem2(timeValueItemResults_metro));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stateUSResult;
    }

    /**
     * 租金回报
     *
     * @param list_rents
     * @param list_homes
     * @return
     */
    public List<DTOTimeSeriesItem> getRentalYield(List<TimeValueItemResult> list_rents, List<TimeValueItemResult> list_homes) {
        if (list_rents == null || list_homes == null || list_rents.size() == 0 || list_homes.size() == 0) {
            return null;
        }
        List<DTOTimeSeriesItem> items = new ArrayList<>();
        try {
            if (list_rents.size() > 0) {
                for (TimeValueItemResult item : list_rents) {
                    DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
                    String rent_year_month = item.getTime();
                    Double rent_value = Double.valueOf(item.getValue());
                    timeSeriesItem.setTime(item.getTime());
                    for (TimeValueItemResult home : list_homes) {
                        String home_year_month = home.getTime();
                        Double home_value = Double.valueOf(home.getValue());
                        Double reward = 0.00; //租金回报
                        if (rent_year_month.equals(home_year_month)) {
                            if (home_value != null && home_value != 0) {
                                reward = rent_value * 12 / home_value;
                            }
                            timeSeriesItem.setValue(reward);
                            break;
                        }
                    }
                    if (timeSeriesItem.getTime() != null && timeSeriesItem.getValue() != null) {
                        items.add(timeSeriesItem);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return items;
    }

    /**
     * 房租中位数时间图
     *
     * @param list
     * @return
     */
    public List<DTOTimeSeriesItem> getMedianRent(List<TimeValueItemResult> list) {
        return timeSeriesDataToTimeSeriesItem2(list);
//        List<DTOTimeSeriesItem> items = new ArrayList<>();
//        try {
//            if (list.size() > 0) {
//                for (TimeValueItemResult item : list) {
//                    DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
//                    timeSeriesItem.setTime(item.getTime());
//                    timeSeriesItem.setValue(Double.valueOf(item.getValue()));
//                    items.add(timeSeriesItem);
//                }
//            }
//
//            items =   timeSeriesDataToTimeSeriesItem2(list);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return items;
    }

    /**
     * 房价/租金关系
     *
     * @param rent_list
     * @param price_list
     * @return
     */
    public DTOPricesRentsResult getPricesRents(List<TimeValueItemResult> rent_list, List<TimeValueItemResult> price_list) {
        DTOPricesRentsResult list = new DTOPricesRentsResult();
        try {
            //房价
            List<DTOTimeSeriesItem> rent_items = timeSeriesDataToTimeSeriesItem(rent_list);
            list.setRents(rent_items);

            //租金
            List<DTOTimeSeriesItem> price_items = timeSeriesDataToTimeSeriesItem(price_list);
            list.setPrices(price_items);

            //租金回报
            List<DTOTimeSeriesItem> rewards = new ArrayList<>();
            if (rent_items.size() > 0 && price_items.size() > 0) {
                for (int i = 0; i < rent_items.size(); i++) {
                    DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
                    timeSeriesItem.setTime(rent_items.get(i).getTime());
                    Double reward = rent_items.get(i).getValue() * 12 / price_items.get(i).getValue() * 100;
                    timeSeriesItem.setValue(reward);
                    rewards.add(timeSeriesItem);
                }
                for (DTOTimeSeriesItem rent_item : rent_items) {
                    for (DTOTimeSeriesItem price_item : price_items) {
                        if (rent_item.getTime().equals(price_item.getTime())) {
                            DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
                            timeSeriesItem.setTime(rent_item.getTime());
                            Double reward = 0.0;
                            Double price = price_item.getValue();
                            if (price != 0) {
                                reward = rent_item.getValue() * 12 / price * 100;
                            }
                            timeSeriesItem.setValue(reward);
                            rewards.add(timeSeriesItem);
                        }
                    }
                }
                list.setRatio(rewards);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * SFR/condo房价变化
     *
     * @param zipcode
     * @return
     */
    public DTOSFRCondoResult getSFRCondo(String zipcode) {
        DTOSFRCondoResult sfrCondoResult = new DTOSFRCondoResult();
        try {
            Date etime = new Date();
            Date btime = DateUtils.addYear(etime, -10);
            String time = "10";

            String key_Zip_Zhvi_Condominum = "zillow/Zip_Zhvi_Condominum/" + zipcode + ".json";
            List<TimeValueItemResult> allCondos = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_Condominum, time);

            String key_Zip_Zhvi_SingleFamilyResidence = "zillow/Zip_Zhvi_SingleFamilyResidence/" + zipcode + ".json";
            List<TimeValueItemResult> allSfh = downloadService.downloadTimeValuesFromOSS(key_Zip_Zhvi_SingleFamilyResidence, time);

            List<DTOTimeSeriesItem> list_1 = timeSeriesDataToTimeSeriesItem(allCondos);
            List<DTOTimeSeriesItem> list_2 = timeSeriesDataToTimeSeriesItem(allSfh);

            sfrCondoResult.setAll_sfh(list_1);
            sfrCondoResult.setAll_condos(list_2);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sfrCondoResult;
    }

    /**
     * 平均家庭收入
     *
     * @param truliaData
     * @return
     */
    public DTOIncome getAverageHouseHoldIncome(TruliaData truliaData) {
        DTOIncome income = new DTOIncome();
        //全美平均家庭收入
        income.setUs(usaConfig.getAverage_household_income());
        if (truliaData != null) {
            //中位家庭收入
            income.setLocal(truliaData.getDemoHouseholdIncome());
            //州平均家庭收入
            income.setState(null);
        }
        return income;
    }

    /**
     * 房租
     *
     * @param zipcode
     * @return
     */
    public List<DTOTimeSeriesItem> getRent(String zipcode) {
        List<DTOTimeSeriesItem> items = new ArrayList<>();
        try {
            Date etime = new Date();
            Date btime = DateUtils.addYear(etime, -10);
            String key = "zillow/Zip_ZriPerSqft_AllHomes/" + zipcode + ".json";
            String time = "10";
            items = timeSeriesDataToTimeSeriesItem(downloadService.downloadTimeValuesFromOSS(key, time));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return items;
    }

    /**
     * 1b/2b/3b/4b/5b+房价变化
     *
     * @param zipcode
     * @return
     */
    public DTOBedRoomResult getBedRoom(String zipcode) {
        try {
            Date etime = new Date();
            Date btime = DateUtils.addYear(etime, -5);

            String key1 = "zillow/Zip_Zhvi_1bedroom/" + zipcode + ".json";
            String key2 = "zillow/Zip_Zhvi_2bedroom/" + zipcode + ".json";
            String key3 = "zillow/Zip_Zhvi_3bedroom/" + zipcode + ".json";
            String key4 = "zillow/Zip_Zhvi_4bedroom/" + zipcode + ".json";
            String key5 = "zillow/Zip_Zhvi_5BedroomOrMore/" + zipcode + ".json";

            String time = "5";

            List<TimeValueItemResult> list1 = downloadService.downloadTimeValuesFromOSS(key1, time);
            List<TimeValueItemResult> list2 = downloadService.downloadTimeValuesFromOSS(key2, time);
            List<TimeValueItemResult> list3 = downloadService.downloadTimeValuesFromOSS(key3, time);
            List<TimeValueItemResult> list4 = downloadService.downloadTimeValuesFromOSS(key4, time);
            List<TimeValueItemResult> list5 = downloadService.downloadTimeValuesFromOSS(key5, time);

            List<DTOTimeSeriesItem> list_1 = timeSeriesDataToTimeSeriesItem(list1);
            List<DTOTimeSeriesItem> list_2 = timeSeriesDataToTimeSeriesItem(list2);
            List<DTOTimeSeriesItem> list_3 = timeSeriesDataToTimeSeriesItem(list3);
            List<DTOTimeSeriesItem> list_4 = timeSeriesDataToTimeSeriesItem(list4);
            List<DTOTimeSeriesItem> list_5 = timeSeriesDataToTimeSeriesItem(list5);

            DTOBedRoomResult bedRoomResult = new DTOBedRoomResult();

            bedRoomResult.setOne_bed(list_1);
            bedRoomResult.setTwo_bed(list_2);
            bedRoomResult.setThree_bed(list_3);
            bedRoomResult.setFour_bed(list_4);
            bedRoomResult.setFive_bed(list_5);

            return bedRoomResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<DTOTimeSeriesItem> timeSeriesDataToTimeSeriesItem(List<TimeValueItemResult> list) {
        List<DTOTimeSeriesItem> items = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (TimeValueItemResult item : list) {
                DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
                timeSeriesItem.setTime(DateUtils.dateFormat(item.getTime(), "yyyy-MM"));
                timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                items.add(timeSeriesItem);
            }
        }
        return items;
    }

    public List<DTOTimeSeriesItem> timeSeriesDataToTimeSeriesItem2(List<TimeValueItemResult> list) {
        List<DTOTimeSeriesItem> items = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (TimeValueItemResult item : list) {
                if (item.getValue() != null) {
                    DTOTimeSeriesItem timeSeriesItem = new DTOTimeSeriesItem();
                    timeSeriesItem.setTime(item.getTime());
                    timeSeriesItem.setValue(Double.valueOf(item.getValue()));
                    items.add(timeSeriesItem);
                }
            }
        }
        return items;
    }
}
